module DotNetEvents
  module ClassMethods
    def declare_event( *events )
      events.each do |event|
        define_handler_methods( event )
      end
    end

    def define_handler_methods( event )
      event_name = event.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
      class_eval <<-EOS
        def handlers( event_name )
          @event_handlers ||= Hash.new
          @event_handlers[ event_name ] ||= []
        end

        def add_#{event_name}( handler )
          handlers( :#{event_name} ) << handler
        end

        def remove_#{event_name}( handler )
          handlers( :#{event_name} ).delete handler
        end

        def #{event_name}( sender, args )
          handlers( :#{event_name} ).each do |handler|
            handler.invoke sender, args
          end
      end
      EOS
    end
  end

  def self.included(receiver)
    receiver.extend ClassMethods
  end
end